package com.youlu.campus.service.course;

import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.course.dto.TxResult;
import com.youlu.campus.service.utils.PayUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;

/**
 * @author : [dengbo]
 * @className : TxThirdService
 * @description : [腾讯第三方]
 * @createTime : [2022/12/18 19:57]
 */
@Service
@Slf4j
public class TxThirdService {

    @Value("${tx.card.merchantId}")
    private String cardMerchantId;
    @Value("${tx.card.key}")
    private String cardKey;
    @Value("${tx.card.notify}")
    private String cardNotify;
    @Value("${tx.vip.merchantId}")
    private String vipMerchantId;
    @Value("${tx.vip.key}")
    private String vipKey;

    @Autowired
    private RestTemplate restTemplate;


    private static final String DOMAIN = "https://lx.huilankeji.cn";

    private static final String QUERY_GOODS_URL = "api/supply/products-info";
    private static final String CREATE_ORDER_URL = "api/supply/orders-submit";
    private static final String CREATE_EXCHANGE_CODE_URL = "api/supply/exchange-codes/generate";
    private static final String CANCEL_EXCHANGE_CODE_URL = "api/supply/exchange-codes/lost";

    public Map<String, Object> getGoodsInfo(String goodsCode) {
        Map<String, String> param = new HashMap<>();
        param.put("merchant_id", cardMerchantId);
        param.put("product_id", goodsCode);
        param.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        try {
            String sign = WXPayUtil.generateSignature(param, cardKey, WXPayConstants.SignType.MD5);
            param.put("sign", sign);
        } catch (Exception e) {
            throw new BusinessException("解析参数异常");
        }
        String urlParam = PayUtil.createLinkString(param);
        String url = DOMAIN + "/" + QUERY_GOODS_URL + "?" + urlParam;
        log.info("query goods param:{}", param);
        ResponseEntity<TxResult> re = restTemplate.getForEntity(url, TxResult.class);
        if (!"ok".equals(re.getBody().getCode())) {
            throw new BusinessException(re.getBody().getMessage());
        }
        return (Map<String, Object>) re.getBody().getData();
    }

    /**
     * @param goodsCode
     * @param num       生成兑换码数量
     * @param startTime 格式 Y-m-d H:i:s
     * @param endTime   格式 Y-m-d H:i:s
     * @return
     */
    public Map<String, Object> generateRedeemCode(String goodsCode, int num, String startTime, String endTime) {
        Map<String, String> param = new HashMap<>();
        param.put("merchant_id", vipMerchantId);
        param.put("product_id", goodsCode);
        param.put("number", String.valueOf(num));
        if (StringUtils.isNotBlank(startTime)) {
            param.put("active_time", startTime);
        }
        if (StringUtils.isNotBlank(endTime)) {
            param.put("deadline", endTime);
        }
        param.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        try {
            String sign = WXPayUtil.generateSignature(param, vipKey, WXPayConstants.SignType.MD5);
            param.put("sign", sign);
        } catch (Exception e) {
            throw new BusinessException("解析参数异常");
        }
        String url = DOMAIN + "/" + CREATE_EXCHANGE_CODE_URL;
        log.info("generate redeem code param:{}", param);
        ResponseEntity<TxResult> re = restTemplate.postForEntity(url, param, TxResult.class);
        if (!"ok".equals(re.getBody().getCode())) {
            throw new BusinessException(re.getBody().getMessage());
        }
        return (Map<String, Object>) re.getBody().getData();
    }

    /**
     * 取消兑换码数量
     *
     * @param codeList
     * @return
     */
    public Map<String, Object> cancelRedeemCode(Collection<String> codeList) {
        if (CollectionUtils.isEmpty(codeList)) {
            throw new BusinessException("兑换码为空");
        }
        String codeStr = JSONObject.toJSONString(codeList);
        Map<String, String> param = new HashMap<>();
        param.put("merchant_id", vipMerchantId);
        param.put("code_list", codeStr);
        param.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        try {
            String sign = WXPayUtil.generateSignature(param, vipKey, WXPayConstants.SignType.MD5);
            param.put("sign", sign);
        } catch (Exception e) {
            throw new BusinessException("解析参数异常");
        }
        String url = DOMAIN + "/" + CANCEL_EXCHANGE_CODE_URL;
        log.info("cancel redeem code param:{}", param);
        ResponseEntity<TxResult> re = restTemplate.postForEntity(url, param, TxResult.class);
        if (!"ok".equals(re.getBody().getCode())) {
            throw new BusinessException(re.getBody().getMessage());
        }
        return (Map<String, Object>) re.getBody().getData();
    }

    public Map<String, Object> createOrder(String goodsCode, String chargeAccount, String orderNo) {
        Map<String, String> param = new HashMap<>();
        param.put("merchant_id", cardMerchantId);
        param.put("product_id", goodsCode);
        param.put("quantity", String.valueOf(1));
        param.put("recharge_account", chargeAccount);
        param.put("merchant_order_id", orderNo);
        param.put("notify_url", cardNotify);
        param.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000));
        try {
            String sign = WXPayUtil.generateSignature(param, cardKey, WXPayConstants.SignType.MD5);
            param.put("sign", sign);
        } catch (Exception e) {
            throw new BusinessException("解析参数异常");
        }
        String url = DOMAIN + "/" + CREATE_ORDER_URL;
        log.info("orderNo:{} request param:{}", orderNo, param);
        ResponseEntity<TxResult> re = restTemplate.postForEntity(url, param, TxResult.class);
        log.info("orderNo:{} create order re:{}", orderNo, re.getBody());
        if (!"ok".equals(re.getBody().getCode())) {
            throw new BusinessException(re.getBody().getMessage());
        }
        return (Map<String, Object>) re.getBody().getData();
    }
}
